package com.example.springboot.service.impl;;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.entity.Book;
import com.example.springboot.entity.Borrow;
import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.mapper.BookMapper;
import com.example.springboot.mapper.BorrowMapper;
import com.example.springboot.service.IBorrowService;
import com.example.springboot.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

@Service
public class BorrowServiceImpl extends ServiceImpl<BorrowMapper, Borrow> implements IBorrowService{

    @Autowired
    private BookMapper bookMapper;

    @Override
    public boolean save(Borrow entity) {
        // 1、后台也对库存做校验，如果为0，未出"库存不足"的提示
        Book book = bookMapper.selectById(entity.getBookId());
        if (book.getStore() == 0){
            throw new ServiceException("图书库存不足，无法借阅~");
        }

        // 1、修改图书库存
        book.setStore(book.getStore() - 1);
        bookMapper.updateById(book);

        Borrow one = super.getOne(new LambdaQueryWrapper<Borrow>().eq(Borrow::getUserId, TokenUtils.getCurrentUser().getId()).eq(Borrow::getBookId, entity.getBookId()).eq(Borrow::getState,"借阅中"));
        if (Objects.nonNull(one)){
            throw new ServiceException("您选择的图书当前正在借阅中，请重新选择~");
        }

        // 2、判断时间大小
        // 定义时间格式（需与字符串格式完全一致）
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 转换为LocalDate对象
        LocalDate today = LocalDate.now();
        LocalDate startDate = LocalDate.parse(entity.getStartDate(), formatter);
        LocalDate endDate = LocalDate.parse(entity.getEndDate(), formatter);

        // 2.1 跟今天做比较，如果开始时间跟结束时间都小于今天的时间，给出提示
        if (startDate.isBefore(today) || endDate.isBefore(today)){
            throw new ServiceException("您选择的开始时间或结束时间在今天之前，请重新选择~");
        }

        // 2.2 开始时间 > 结束时间
        if (startDate.isAfter(endDate)){
            throw new ServiceException("您选择的开始时间在结束时间之后，请重新选择~");
        }
        return super.save(entity);
    }

    @Override
    public boolean updateById(Borrow entity) {
        entity.setState("已归还");
        entity.setActualDate(DateUtil.now());

        // 修改图书库存
        Book book = bookMapper.selectById(entity.getBookId());
        if (Objects.nonNull(book)){
            book.setStore(book.getStore() + 1);
            bookMapper.updateById(book);
        }
        return super.updateById(entity);
    }

    @Override
    public boolean removeById(Borrow entity) {
        return super.removeById(entity);
    }

    @Override
    public boolean removeBatchByIds(Collection<?> list) {
        return super.removeBatchByIds(list);
    }

    @Override
    public List<Borrow> list() {
        return super.list();
    }

    @Override
    public Borrow getById(Serializable id) {
        return super.getById(id);
    }

    @Override
    public <E extends IPage<Borrow>> E page(E page, Wrapper<Borrow> queryWrapper) {
        E page1 = super.page(page, queryWrapper);
        page1.getRecords().stream().forEach(borrow -> {
            borrow.setBook(bookMapper.selectById(borrow.getBookId()));
        });
        return page1;
    }
    @Override
    public JSONObject borrowCount() {
        JSONObject result = new JSONObject();
        result.put("allCount",super.count());
        result.put("startCount",super.count(new LambdaQueryWrapper<Borrow>().eq(Borrow::getState,"借阅中")));
        result.put("endCount",super.count(new LambdaQueryWrapper<Borrow>().eq(Borrow::getState,"已归还")));
        return result;
    }

    @Override
    public JSONObject borrowEcharts() {
        List<Long> y = new ArrayList<>();
        for (String day: last30Days()){
            Long borrows = super.count(new LambdaQueryWrapper<Borrow>().like(Borrow::getStartDate, day));
            y.add(borrows);
        }

        JSONObject result = new JSONObject();
        result.set("x",last30Days());
        result.set("y",y);
        return result;
    }

    private List<String> last30Days(){
        LocalDate today = LocalDate.now();
        List<String> last30DaysDates = new ArrayList<>();

        // 循环生成30天前到今天的所有日期
        for (int i = 30; i >= 0; i--) {
            LocalDate date = today.minusDays(i);
            last30DaysDates.add(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        return last30DaysDates;
    }

}
